home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / gfx / x11 / xmountains.lha / src / xmountains.c < prev   
C/C++ Source or Header  |  1997-08-23  |  15KB  |  622 lines

  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include "crinkle.h"
  4. #include "paint.h"
  5. #include "global.h"
  6. #include "patchlevel.h"
  7. #include "copyright.h"
  8. #include <exec/exec.h>
  9. #include <dos/dos.h>
  10.  
  11. #define VERSION 2
  12. #define SIDE 1.0
  13.  
  14. char scroll_Id[]="$Id: xmountains.c,v 1.32 1995/06/12 18:58:04 spb Exp spb $";
  15.  
  16. extern char *display;
  17. extern char *geom;
  18.  
  19. /*{{{my version on getopt*/
  20. int optind=1;
  21. char *optarg;
  22. int opterr=1;
  23.  
  24. int getopt (argc, argv, pat)
  25. int argc;
  26. char **argv;
  27. char *pat;
  28. {
  29.   char *flag;
  30.   
  31.   if((optind >= argc) || (argv[optind][0] != '-'))
  32.   {
  33.     return -1;
  34.   }
  35.   if( argv[optind][1] == '-' )
  36.   {
  37.     optind++;
  38.     return -1;
  39.   }
  40.   if( argv[optind][1] == ':' )
  41.   {
  42.     if( opterr )
  43.     {
  44.       fprintf(stderr,"getopt: found \":\" in optstring\n");
  45.     }
  46.     return '?';
  47.   }
  48.   for(flag=pat;*flag;flag++)
  49.   {
  50.     if( *flag == argv[optind][1] )
  51.     {
  52.       optind++;
  53.       if( *(flag+1) == ':' )
  54.       {
  55.         if(optind >= argc )
  56.         {
  57.           if( opterr )
  58.           {
  59.             fprintf(stderr,"getopt: no option for flag %c\n",*flag);
  60.           }
  61.           return '?';
  62.         }
  63.         optarg = argv[optind];
  64.         optind++;
  65.       }
  66.       return *flag;
  67.     }
  68.       
  69.   }
  70.   if( opterr )
  71.   {
  72.     fprintf(stderr,"getopt: flag %s not recognized\n",argv[optind]);
  73.   }
  74.   optind++;
  75.   return '?';
  76. }
  77. /*}}}*/
  78.  
  79. /*{{{  Col *next_col(int paint, int reflec) */
  80. Col *next_col (paint, reflec)
  81. int paint;
  82. int reflec;
  83. {
  84.   Col *res;
  85.   int i,offset=0;
  86.   
  87.   /*{{{  update strips */
  88.   if(paint)
  89.   {
  90.     if(reflec)
  91.     {
  92.       res = mirror( a_strip,b_strip,shadow);
  93.     }else{
  94.       res = camera( a_strip,b_strip,shadow);
  95.     }
  96.   }else{
  97.     res = makemap(a_strip,b_strip,shadow);
  98.   }
  99.   free(a_strip);
  100.   a_strip=b_strip;
  101.   b_strip = extract( next_strip(top) );
  102.   /*}}}*/
  103.  
  104.   /*{{{update the shadows*/
  105.   /* shadow_slip is the Y component of the light vector.
  106.    * The shadows can only step an integer number of points in the Y
  107.    * direction so we maintain shadow_register as the deviation between
  108.    * where the shadows are and where they should be. When the magnitude of
  109.    * this gets larger then 1 the shadows are slipped by the required number of
  110.    * points.
  111.    * This will not work for very oblique angles so the horizontal angle
  112.    * of illumination should be constrained.
  113.    */
  114.   shadow_register += shadow_slip;
  115.   if( shadow_register >= 1.0 )
  116.   {
  117.     /*{{{negative offset*/
  118.     while( shadow_register >= 1.0 )
  119.     {
  120.       shadow_register -= 1.0;
  121.       offset++;
  122.     }
  123.     for(i=width-1 ; i>=offset ; i--)
  124.     {
  125.       shadow[i] = shadow[i-offset]-delta_shadow;
  126.       if( shadow[i] < b_strip[i] )
  127.       {
  128.         shadow[i] = b_strip[i];
  129.       }
  130.       /*{{{  stop shadow at sea level */
  131.       if( shadow[i] < sealevel )
  132.       {
  133.         shadow[i] = sealevel;
  134.       }
  135.       /*}}}*/
  136.     }
  137.     for(i=0;i<offset;i++)
  138.     {
  139.       shadow[i] = b_strip[i];
  140.       /*{{{  stop shadow at sea level*/
  141.       if( shadow[i] < sealevel )
  142.       {
  143.         shadow[i] = sealevel;
  144.       }
  145.       /*}}}*/
  146.     }
  147.     /*}}}*/
  148.   }else if( shadow_register <= -1.0 ){
  149.     /*{{{positive offset*/
  150.     while( shadow_register <= -1.0 )
  151.     {
  152.       shadow_register += 1.0;
  153.       offset++;
  154.     }
  155.     for(i=0 ; i<width-offset ; i++)
  156.     {
  157.       shadow[i] = shadow[i+offset]-delta_shadow;
  158.       if( shadow[i] < b_strip[i] )
  159.       {
  160.         shadow[i] = b_strip[i];
  161.       }
  162.       /*{{{  stop shadow at sea level */
  163.       if( shadow[i] < sealevel )
  164.       {
  165.         shadow[i] = sealevel;
  166.       }
  167.       /*}}}*/
  168.     }
  169.     for(;i<width;i++)
  170.     {
  171.       shadow[i] = b_strip[i];
  172.       /*{{{  stop shadow at sea level*/
  173.       if( shadow[i] < sealevel )
  174.       {
  175.         shadow[i] = sealevel;
  176.       }
  177.       /*}}}*/
  178.     }
  179.     /*}}}*/
  180.   }else{
  181.     /*{{{no offset*/
  182.     for(i=0 ; i<width ; i++)
  183.     {
  184.       shadow[i] -= delta_shadow;
  185.       if( shadow[i] < b_strip[i] )
  186.       {
  187.         shadow[i] = b_strip[i];
  188.       }
  189.       /*{{{  stop shadow at sea level */
  190.       if( shadow[i] < sealevel )
  191.       {
  192.         shadow[i] = sealevel;
  193.       }
  194.       /*}}}*/
  195.     }
  196.     /*}}}*/
  197.   }
  198.   /*}}}*/
  199.   
  200.   return(res);
  201. }
  202. /*}}}*/
  203. double atof();
  204. #ifdef ANSI
  205. void init_graphics (int, int, int *, int *, int, Gun *, Gun *, Gun *);
  206. void finish_graphics();
  207. void plot_pixel (int, int, unsigned char);
  208. void scroll_screen ( int );
  209. void zap_events( int );
  210. #else
  211. void init_graphics ();
  212. void finish_graphics();
  213. void plot_pixel ();
  214. void scroll_screen ();
  215. void zap_events();
  216. #endif
  217.  
  218. void finish_prog();
  219.  
  220. int s_height=768, s_width=1024;
  221. int mapwid;
  222.  
  223.  
  224. /*{{{void plot_column(p,map,reflec,snooze)*/
  225. void plot_column(p,map,reflec,snooze)
  226. int p;
  227. int map;
  228. int reflec;
  229. int snooze;
  230. {
  231.   Col *l;
  232.   int j;
  233.  
  234.   if ((SetSignal(0,0)&SIGBREAKF_CTRL_C)!=0)
  235.     exit(0);
  236.   
  237.   l = next_col(1-map,reflec); 
  238.   if( map )
  239.   {
  240.     for( j=0 ;j<(s_height-mapwid); j++)
  241.     {
  242.       plot_pixel(p,((s_height-1)-j),BLACK);
  243.     }
  244.     for(j=0; j<mapwid ; j++)
  245.     {
  246.       plot_pixel(p,((mapwid-1)-j),l[j]);
  247.     }
  248.   }else{
  249.     for(j=0 ; j<height ; j++)
  250.     {
  251.       /* we assume that the scroll routine fills the
  252.        * new region with a SKY value. This allows us to
  253.        * use a testured sky for B/W displays
  254.        */
  255.       if( l[j] != SKY )
  256.       {
  257.         plot_pixel(p,((s_height-1)-j),l[j]);
  258.       }
  259.     }
  260.   }
  261.   free(l);
  262.   flush_region(p,0,1,height,p,0);
  263.   zap_events(snooze);
  264. }
  265. /*}}}*/
  266.  
  267. main (argc,argv)
  268. int argc;
  269. char **argv;
  270. {
  271.   int i,p;
  272.  
  273.   int repeat=20;
  274.   int map = 0;
  275.   int reflec = 0;
  276.   int root= 0;
  277.  
  278.   int c, errflg=0;
  279.   extern char *optarg;
  280.   extern int optind;
  281.   char *mesg[2];
  282.   Gun *clut[3];
  283.   FILE *pidfile;
  284.   
  285.   struct Task * ptask;
  286.  
  287.   ptask=FindTask(0);
  288.   SetTaskPri(ptask,-2);
  289.  
  290.  
  291.  
  292.   /*{{{handle command line flags*/
  293.   mesg[0]="false";
  294.   mesg[1]="true";
  295.   while((c = getopt(argc,argv,"bxmqMEHl:r:f:t:I:A:S:T:W:C:a:p:B:n:R:g:d:c:e:v:Z:s:X:Y:P:F:G:"))!= -1)
  296.   {
  297.     switch(c){
  298.       case 'b':
  299.         root = 1- root;
  300.         break;                      /* run on root window */
  301.       case 'x':
  302.         cross = 1- cross;
  303.         break;                      /* use cross updates */
  304.       case 'E':
  305.         e_events = 1 - e_events;
  306.         break;
  307.       case 'q':
  308.         request_clear = 1 - request_clear;
  309.         break;
  310.       case 'm':                     /* Map view only */
  311.         map = 1 - map;
  312.         break;
  313.       case 'M':                     /* put in reflections */
  314.         reflec = 1 - reflec;
  315.         break;
  316.       case 'l':                     /* Set # levels of recursion */
  317.          levels = atoi( optarg );
  318.          if( levels < 2 )
  319.          {
  320.            levels = 2;
  321.          }
  322.          break;
  323.       case 'F':                     /* Set # levels to force front to mean */
  324.          slope = atoi( optarg );
  325.          break;
  326.       case 's':                     /* Set smoothing parameter */
  327.          smooth = atoi( optarg );
  328.          break;
  329.       case 't':                     /* Set width of lowest level */
  330.          stop = atoi( optarg );
  331.          if( stop < 0 )
  332.          {
  333.            stop = 0;
  334.          }
  335.          break;
  336.       case 'r':
  337.          repeat = atoi( optarg );
  338.          if( repeat < 0 )
  339.          {
  340.            repeat = -repeat;
  341.            i=-1;
  342.          }else{
  343.            i=1;
  344.          }
  345.          if( repeat < 1 )
  346.          {
  347.            repeat = 1;
  348.          }
  349.          /* we want repeat to be a multiple of 2 as we are using
  350.           * a textured field for the sky.
  351.           */
  352.          repeat = i*(2 * ((repeat +1)/2));
  353.          break;
  354.       case 'B':                     /* set band_size */
  355.          band_size = atoi( optarg );
  356.          if( band_size < 2 )
  357.          {
  358.            band_size=2;
  359.          }
  360.          n_col = (BAND_BASE + (N_BANDS * band_size));
  361.          break;
  362.       case 'n':                     /* set max number of colours */
  363.          n_col = atoi( optarg );
  364.          if( n_col < MIN_COL )
  365.          {
  366.            n_col = MIN_COL;
  367.          }
  368.          band_size = (n_col - BAND_BASE)/N_BANDS;
  369.          n_col = (BAND_BASE + (N_BANDS * band_size));
  370.          break;
  371.       case 'R':                     /* set seed, read clock if 0 */
  372.          seed = atoi( optarg );
  373.          break;
  374.       case 'Z':                     /* put sleep into wait events */
  375.          snooze_time = atoi( optarg );
  376.          if( snooze_time < 0 )
  377.          {
  378.            snooze_time = 0;
  379.          }
  380.          break;
  381.       case 'P':
  382.          pidfile = fopen(optarg,"w");
  383.          if( pidfile )
  384.          {
  385.            fprintf(pidfile,"%d\n",-1);
  386.            fclose(pidfile);
  387.          }else{
  388.            perror(optarg);
  389.          }
  390.          break;
  391.       case 'f':                     /* set fractal dimension */
  392.          fdim = atof( optarg );
  393.          if( fdim < 0.5 )
  394.          {
  395.           fdim=0.5;
  396.          }
  397.          if( fdim > 1.0 )
  398.          {
  399.           fdim=1.0;
  400.          }
  401.          break;
  402.       case 'I':                     /* set Illumination angle */
  403.          phi = ((PI * atof( optarg ))/180.0);
  404.          if ( phi < 0.0 )
  405.          {
  406.            phi=0.0;
  407.          }
  408.          if( phi > PI/2.0 )
  409.          {
  410.            phi = PI/2.0;
  411.          }
  412.          break;
  413.       case 'A':                     /* set Illumination angle (horizontal)*/
  414.          alpha = ((PI * atof( optarg ))/180.0);
  415.          if( alpha < -PI/3.0 )
  416.          {
  417.            alpha = -PI/3.0;
  418.          }
  419.          if( alpha > PI/3.0 )
  420.          {
  421.            alpha = PI/3.0;
  422.          }
  423.          break;
  424.       case 'X':                     /* set mix */
  425.          mix = atof( optarg );
  426.          break;
  427.       case 'Y':                     /* set midmix */
  428.          midmix = atof( optarg );
  429.          break;
  430.       case 'S':                     /* set stretch */
  431.          stretch = atof( optarg );
  432.          break;
  433.       case 'W':                     /* set sealevel */
  434.          sealevel = atof( optarg );
  435.          break;
  436.       case 'G':                     /* set forceheight */
  437.          forceheight = atof( optarg );
  438.          break;
  439.       case 'T':                     /* set shift */
  440.          shift = atof( optarg );
  441.          break;
  442.       case 'C':
  443.          contour = atof( optarg );
  444.          break;
  445.       case 'a':                     /* set altitude */
  446.          altitude = atof( optarg );
  447.          break;
  448.       case 'p':                     /* set distance */
  449.          distance = atof( optarg );
  450.          break;
  451.       case 'c':
  452.          contrast = atof( optarg );
  453.          if( contrast < 0.0 )
  454.          {
  455.           contrast=0.0;
  456.          }
  457.          break;
  458.       case 'e':
  459.          ambient = atof( optarg );
  460.          if( ambient < 0.0 )
  461.          {
  462.           ambient = 0.0;
  463.          }
  464.          if( ambient > 1.0 )
  465.          {
  466.           ambient=1.0;
  467.          }
  468.          break;
  469.       case 'v':
  470.          vfract = atof( optarg );
  471.          if( vfract < 0.0 )
  472.          {
  473.           vfract = 0.0;
  474.          }
  475.          break;
  476.       case 'g':
  477.          geom = optarg;
  478.          break;
  479.       case 'd':
  480.          display = optarg;
  481.          break;
  482.       case 'H':
  483.          print_algorithm();
  484.          errflg++;
  485.          break;
  486.       case '?':
  487.          errflg++;
  488.     }
  489.   }
  490.   if( errflg )
  491.   {
  492.     fprintf(stderr,"%s: version %d.%d\n",argv[0],VERSION,PATCHLEVEL);
  493.     fprintf(stderr,"usage: %s -[bqgdPEmMrBZIASFTCapcevfRltxsXYH]\n",argv[0]);
  494.     fprintf(stderr," -b       [%s] use root window \n",mesg[root]);
  495.     fprintf(stderr," -q       [%s] reset root window on exit\n",mesg[request_clear]);
  496.     fprintf(stderr," -g string     window geometry\n");
  497.     fprintf(stderr," -d string     display\n");
  498.     fprintf(stderr," -P filename   write PID to file\n");
  499.     fprintf(stderr," -E       [%s] toggle explicit expose events \n",mesg[e_events]);
  500.     fprintf(stderr," -m       [%s] print map \n",mesg[map]);
  501.     fprintf(stderr," -M       [%s] implement reflections \n",mesg[reflec]);
  502.     fprintf(stderr," -r int   [%d] # columns before scrolling \n",repeat);
  503.     fprintf(stderr," -B int   [%d] # shades in a colour band\n",band_size);
  504.     fprintf(stderr," -n int   [%d] # number of colours\n",n_col);
  505.     fprintf(stderr," -Z int   [%d] time to sleep before scrolling\n",snooze_time);
  506.     fprintf(stderr," -I float [%f] vertical angle of light \n",(phi*180.0)/PI);
  507.     fprintf(stderr," -A float [%f] horizontal angle of light \n",(alpha*180.0)/PI);
  508.     fprintf(stderr," -S float [%f] vertical stretch \n",stretch);
  509.     fprintf(stderr," -T float [%f] vertical shift \n",shift);
  510.     fprintf(stderr," -W float [%f] sealevel \n",sealevel);
  511.     fprintf(stderr," -F int   [%d] reduce variation in the foreground \n",slope);
  512.     fprintf(stderr," -G float [%f] average foreground height \n",forceheight);
  513.     fprintf(stderr," -C float [%f] contour parameter \n",contour);
  514.     fprintf(stderr," -a float [%f] altitude of viewpoint \n",altitude);
  515.     fprintf(stderr," -p float [%f] distance of viewpoint \n",distance);
  516.     fprintf(stderr," -c float [%f] contrast\n",contrast);
  517.     fprintf(stderr," -e float [%f] ambient light level\n",ambient);
  518.     fprintf(stderr," -v float [%f] vertical light level\n",vfract);
  519.     fprintf(stderr,"Fractal options:\n");
  520.     fprintf(stderr," -f float [%f] fractal dimension \n",fdim);
  521.     fprintf(stderr," -R int   [%d] rng seed, read clock if 0 \n",seed);
  522.     fprintf(stderr," -l int   [%d] # levels of recursion \n",levels);
  523.     fprintf(stderr," -t int   [%d] # non fractal iterations \n",stop);
  524.     fprintf(stderr," -x       [%s] cross update \n",mesg[cross]);
  525.     fprintf(stderr," -s       [%x] smoothing (0-7)\n",smooth);
  526.     fprintf(stderr," -X float [%f] fraction of old value for rg2 & rg3\n",mix);
  527.     fprintf(stderr," -Y float [%f] fraction of old value for rg1\n",midmix);
  528.     fprintf(stderr," -H            print short description of algorithm.\n");
  529.     exit(1);
  530.   }
  531.   /*}}}*/
  532.   for(i=0 ;i<3 ;i++)
  533.   {
  534.     clut[i] = (Gun *) malloc(n_col * sizeof(Gun));
  535.     if( ! clut[i] )
  536.     {
  537.       fprintf(stderr,"malloc failed for clut\n");
  538.       exit(1);
  539.     }
  540.   }
  541.   set_clut(n_col,clut[0], clut[1], clut[2]);
  542.   init_graphics(root,(! e_events),request_clear,&s_width,&s_height,n_col,clut[0],clut[1],clut[2]);
  543.   for(i=0;i<3;i++)
  544.   {
  545.     free(clut[i]);
  546.   }
  547.  
  548.   height = s_height;
  549.     
  550.   seed_uni(seed);
  551.  
  552.   init_artist_variables();
  553. #if 0
  554.   if( -1 == (int) signal(SIG_DFL, finish_prog ))
  555.   {
  556.     perror(argv[0]);
  557.     exit(1);
  558.   }
  559.   if( -1 == (int) signal(SIG_DFL, finish_prog ))
  560.   {
  561.     perror(argv[0]);
  562.     exit(1);
  563.   }
  564.   if( -1 == (int) signal(SIG_DFL, finish_prog ))
  565.   {
  566.     perror(argv[0]);
  567.     exit(1);
  568.   }
  569.   if( -1 == (int) signal(SIG_DFL, finish_prog ))
  570.   {
  571.     perror(argv[0]);
  572.     exit(1);
  573.   }
  574. #endif
  575.   if( s_height > width )
  576.   {
  577.     mapwid=width;
  578.   }else{
  579.     mapwid=s_height;
  580.   }
  581.   if( repeat > 0 )
  582.   {
  583.     for(p=0 ; p < s_width ; p++)
  584.     {
  585.       plot_column(p,map,reflec,0);
  586.     }
  587.   }else{
  588.     for(p=s_width-1 ; p >=0 ; p--)
  589.     {
  590.       plot_column(p,map,reflec,0);
  591.     }
  592.   }
  593.   while( TRUE )
  594.   {
  595.       /* do the scroll */
  596.       scroll_screen(repeat);
  597.       if(repeat > 0)
  598.       {
  599.         for( p = s_width - repeat ; p < (s_width-1) ; p++ )
  600.         {
  601.           plot_column(p,map,reflec,0);
  602.         }
  603.       }else{
  604.         for( p = -1 - repeat ; p >=0 ; p-- )
  605.         {
  606.           plot_column(p,map,reflec,0);
  607.         }
  608.       }
  609.       plot_column(p,map,reflec,snooze_time);
  610.   }
  611. }
  612.  
  613.     
  614. extern int quit_xmount;
  615.  
  616. void finish_prog()
  617. {
  618.   /* The next time zap_events is called the program will quit */
  619.   quit_xmount=TRUE;
  620. }
  621.  
  622.